梦想不会自己发光,真正闪耀的是那个为梦狂奔的你。献给知行的孩子们!(Eric.He著)
将有限的资源分配给多个需求方,目标是最大化资源利用率 / 收益或最小化资源消耗,每一步选择对当前资源最 “高效” 的分配方式。
本教程以多个资源分配贪心算法案例场景为例,让大家彻底理解以 “局部最优” 推导 “全局最优” 的核心逻辑,并掌握部分背包、最优装载问题的原理及代码实现。
问题描述:
算法解析:
#include <iostream>
#include <vector>
using namespace std;
// 金币结构体:重量、价值
struct Gold {
double weight;//重量
double value;//价值
// 性价比(单位重量价值)
double valuePerWeight() const {
return value / weight;
}
};
// 按性价比降序排序
bool compareGold(const Gold& a, const Gold& b) {
return a.valuePerWeight() > b.valuePerWeight();
}
// 部分背包求解:capacity-背包容量,golds-金币列表,返回最大总价值
double fractionalKnapsack(double capacity, vector<Gold>& golds) {
sort(golds.begin(), golds.end(), compareGold);
double totalValue = 0.0;
double currentWeight = 0.0;
for (auto& item : golds) {
// 能装下整个物品
if (currentWeight + item.weight <= capacity) {
currentWeight += item.weight;
totalValue += item.value;
} else {
// 装剩余部分
double remain = capacity - currentWeight;
totalValue += item.valuePerWeight() * remain;
break; // 背包已满
}
}
return totalValue;
}
int main() {
// 测试:3堆金币,背包容量50
vector<Gold> golds = {{10, 60}, {20, 100}, {30, 120}};
double capacity = 50;
cout << "部分背包最大价值:" << fractionalKnapsack(capacity, golds) << endl;
return 0;
}
部分背包最大价值:240
问题描述:
算法解析:
#include <iostream>
#include <vector>
using namespace std;
// 定义货物包结构体
struct Wrap {
int id; // 包编号
double weight; // 货物重量
double qty; // 货物数量
// 构造函数,方便初始化
Wrap(int i, double w, double q) : id(i), weight(w), qty(q) {}
// 单个重量
double unitWeight() const {
return weight / qty;
}
};
// 排序比较函数:按重量升序排序(轻的在前)
bool compareWrap(const Wrap &a, const Wrap &b) {
return a.unitWeight() < b.unitWeight();
}
// 最优装载问题
// 参数:wraps-货物包结构体数组,maxCapacity最大载重
void optimalLoading(vector<Wrap> wraps, int maxCapacity, vector<int>& selectedIds, int& totalWeight, int& count) {
// 步骤1:按重量升序排序
sort(wraps.begin(), wraps.end(), compareWrap);
// 步骤2:依次选取货物物品,保留包编号
for (const Wrap &wrap : wraps) {
if (totalWeight + wrap.weight <= maxCapacity) {
selectedIds.push_back(wrap.id);
totalWeight += wrap.weight;
count+=wrap.qty;
} else {
break;// 背包已满
}
}
}
int main() {
// 测试:5包货物,载重量100
vector<Wrap> wraps = {{1, 50, 60}, {2, 50, 70}, {3, 50, 80}, {4, 30, 80}, {5, 20, 70}};
double maxCapacity = 100;// 载重量
vector<int> selectedIds;// 已载包编号
int totalWeight = 0;// 已载货物重量
int count = 0;// 已载货物数量
optimalLoading(wraps, maxCapacity, selectedIds, totalWeight, count);
cout << "已载货物重量:" << totalWeight << endl;
cout << "已载货物数量:" << count << endl;
cout << "已载包编号:";
for(int id : selectedIds)
{
cout << id << " ";
}
return 0;
}
已载货物重量:100
已载货物数量:230
已载包编号:5 4 3